package com.baizhi.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Configuration
@Aspect
public class CacheAspect {
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 添加缓存
     * 1.判断要得到的数据在缓存中有没有
     * 2.没有的话 查询数据  查询结果放到缓存中
     * 3.有的话 直接把缓存的结果 返回
     *
     * 环绕增强 需要放行操作  可以获取方法执行的返回值
     */
    @Around("@annotation(com.baizhi.annotation.AddCacheAnnotation)")
    public Object addCache(ProceedingJoinPoint joinPoint) throws Throwable {
//        1.获取类名
        String className = joinPoint.getTarget().getClass().getName();
        System.out.println("类名："+className);

//        2.获取方法名+形参的值
        StringBuffer stringBuffer = new StringBuffer();
        String methodName = joinPoint.getSignature().getName();
        stringBuffer.append(methodName);
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            stringBuffer.append(arg);
        }
        String hashKey = stringBuffer.toString();
        System.out.println("hashKey:"+hashKey);
//        3.判断要得到的数据在缓存中有没有
        HashOperations hashOperations = redisTemplate.opsForHash();

        Object result = hashOperations.get(className, hashKey);

        if (result == null) {
            System.out.println("查询数据库");
//        4.没有的话 查询数据  查询结果放到缓存中
            //        执行放行操作 查询数据库  就是被切的方法执行的返回值结果
            result = joinPoint.proceed();

            Map map = new HashMap();

            map.put(hashKey,result);

            hashOperations.putAll(className,map);

//            设置失效时间 expire 参数1 要设置的key 参数2 时间数 参数3 单位
            redisTemplate.expire(className,10, TimeUnit.SECONDS);

        }else {
            System.out.println("缓存取值");
        }

        return result;
    }
    /**
     * 删除缓存
     *
     * 切注解
     */
    @Before("@annotation(com.baizhi.annotation.DeleteCacheAnnotation)")
    public void deleteCache(JoinPoint joinPoint){
        /**
         * 执行删除缓存
         */
        System.out.println("删除缓存");
//        1.获取类名
        String className = joinPoint.getTarget().getClass().getName();
        System.out.println("要删除的类名："+className);
//        2.删除
        redisTemplate.delete(className);
    }
}
